import { PrismaClient } from '@prisma/client';
import { SinaStockAPI } from '../utils/SinaStockAPI';

// 小分类定义接口
interface SubCategory {
  key: string;
  name: string;
  markets?: string[];
  codePattern?: RegExp;
  description?: string;
}

// 大分类定义接口
interface MainCategory {
  key: string;
  name: string;
  description?: string;
  subCategories: SubCategory[];
}

// 大分类和小分类的层级结构
const CATEGORY_HIERARCHY: MainCategory[] = [
  {
    key: 'a_stock',
    name: 'A股市场',
    description: '中国内地A股市场',
    subCategories: [
      {
        key: 'sh_a',
        name: '上证A股',
        markets: ['SH'],
        codePattern: /^6/,
        description: '上海证券交易所A股（代码以6开头）'
      },
      {
        key: 'sz_a',
        name: '深证A股',
        markets: ['SZ'],
        codePattern: /^00/,
        description: '深圳证券交易所主板A股（代码以00开头）'
      },
      {
        key: 'cy',
        name: '创业板',
        markets: ['SZ'],
        codePattern: /^3/,
        description: '创业板股票（代码以3开头）'
      },
      {
        key: 'kc',
        name: '科创板',
        markets: ['SH'],
        codePattern: /^688/,
        description: '科创板股票（代码以688开头）'
      },
      {
        key: 'bj',
        name: '北交所',
        markets: ['NEEQ'],
        codePattern: /^[48]/,
        description: '北京证券交易所（代码以4、8开头）'
      }
    ]
  },
  {
    key: 'hk_stock',
    name: '香港市场',
    description: '香港交易所股票市场',
    subCategories: [
      {
        key: 'hk_main',
        name: '港股主板',
        markets: ['HK'],
        codePattern: /^[0-9]{5}$/,
        description: '香港主板股票'
      },
      {
        key: 'hk_gem',
        name: '香港创业板',
        markets: ['HK'],
        codePattern: /^8/,
        description: '香港创业板股票（代码以8开头）'
      }
    ]
  },
  {
    key: 'us_stock',
    name: '美股市场',
    description: '美国股票市场',
    subCategories: [
      {
        key: 'nasdaq',
        name: '纳斯达克',
        markets: ['US'],
        description: '纳斯达克交易所股票'
      },
      {
        key: 'nyse',
        name: '纽约证交所',
        markets: ['US'],
        description: '纽约证券交易所股票'
      }
    ]
  },
  {
    key: 'uk_stock',
    name: '英股市场',
    description: '英国股票市场',
    subCategories: [
      {
        key: 'lse',
        name: '伦敦证交所',
        markets: ['UK'],
        description: '伦敦证券交易所股票'
      }
    ]
  }
];

interface StockListQuery {
  market?: string;
  page: number;
  limit: number;
  search?: string;
}

interface HistoryQuery {
  startDate?: string;
  endDate?: string;
  period: string;
}

export class StockService {
  private prisma: PrismaClient;
  private sinaAPI: SinaStockAPI;

  constructor() {
    this.prisma = new PrismaClient();
    this.sinaAPI = new SinaStockAPI();
  }

  // 辅助方法：获取市场ID
  private async getMarketIds(marketCodes: string[]): Promise<number[]> {
    const markets = await this.prisma.market.findMany({
      where: { marketCode: { in: marketCodes } }
    });
    return markets.map(market => market.id);
  }

  // 辅助方法：根据大分类获取股票
  private async getStocksByMainCategory(mainCategoryKey: string) {
    const mainCategory = CATEGORY_HIERARCHY.find(cat => cat.key === mainCategoryKey);
    if (!mainCategory) {
      throw new Error(`找不到${mainCategoryKey}大分类数据`);
    }

    const allStocks = [];
    
    for (const subCategory of mainCategory.subCategories) {
      if (subCategory.markets && subCategory.markets.length > 0) {
        const marketIds = await this.getMarketIds(subCategory.markets);
        
        let subCategoryStocks = [];
        if (subCategory.codePattern) {
          const allMarketStocks = await this.prisma.stock.findMany({
            where: {
              marketId: { in: marketIds },
              status: 1
            },
            include: { 
              market: true,
              realtime: true 
            }
          });
          subCategoryStocks = allMarketStocks.filter(stock => 
            subCategory.codePattern!.test(stock.stockCode) && stock.realtime
          );
        } else {
          subCategoryStocks = await this.prisma.stock.findMany({
            where: {
              marketId: { in: marketIds },
              status: 1
            },
            include: { 
              market: true,
              realtime: true 
            }
          });
          subCategoryStocks = subCategoryStocks.filter(stock => stock.realtime);
        }
        
        allStocks.push(...subCategoryStocks);
      }
    }
    
    return { stocks: allStocks, mainCategory };
  }

  // 获取股票列表
  async getStockList(query: StockListQuery) {
    const { market, page, limit, search } = query;
    const skip = (page - 1) * limit;

    const whereClause: any = {};
    
    if (market) {
      const marketData = await this.prisma.market.findFirst({
        where: { marketCode: market.toUpperCase() }
      });
      if (marketData) {
        whereClause.marketId = marketData.id;
      }
    }

    if (search) {
      whereClause.OR = [
        { stockCode: { contains: search } },
        { stockName: { contains: search } }
      ];
    }

    const [stocks, total] = await Promise.all([
      this.prisma.stock.findMany({
        where: whereClause,
        include: {
          market: true,
          realtime: true
        },
        skip,
        take: limit,
        orderBy: { updatedAt: 'desc' }
      }),
      this.prisma.stock.count({ where: whereClause })
    ]);

    // 转换BigInt为字符串以便JSON序列化
    const processedStocks = stocks.map(stock => ({
      ...stock,
      totalShares: stock.totalShares ? stock.totalShares.toString() : null,
      outstandingShares: stock.outstandingShares ? stock.outstandingShares.toString() : null,
      realtime: stock.realtime ? {
        ...stock.realtime,
        volume: stock.realtime.volume ? stock.realtime.volume.toString() : null
      } : null
    }));

    return {
      data: processedStocks,
      pagination: {
        page,
        limit,
        total,
        totalPages: Math.ceil(total / limit)
      }
    };
  }

  // 获取股票实时数据
  async getRealtimeData(stockId: number) {
    const stock = await this.prisma.stock.findUnique({
      where: { id: stockId },
      include: {
        market: true,
        realtime: true
      }
    });

    if (!stock) {
      throw new Error('股票不存在');
    }

    // 从新浪API获取最新数据
    const realtimeData = await this.sinaAPI.getRealtimeData(
      stock.market.marketCode, 
      stock.stockCode
    );

    // 更新数据库中的实时数据
    if (realtimeData) {
      await this.updateRealtimeData(stockId, realtimeData);
    }

    // 返回更新后的数据
    const result = await this.prisma.stock.findUnique({
      where: { id: stockId },
      include: {
        market: true,
        realtime: true
      }
    });

    if (result) {
      return {
        ...result,
        totalShares: result.totalShares ? result.totalShares.toString() : null,
        outstandingShares: result.outstandingShares ? result.outstandingShares.toString() : null,
        realtime: result.realtime ? {
          ...result.realtime,
          volume: result.realtime.volume ? result.realtime.volume.toString() : null
        } : null
      };
    }

    return result;
  }

  // 获取股票历史数据
  async getHistoryData(stockId: number, query: HistoryQuery) {
    const { startDate, endDate, period } = query;
    
    const whereClause: any = { stockId };
    
    if (startDate) {
      whereClause.tradeDate = { gte: new Date(startDate) };
    }
    
    if (endDate) {
      whereClause.tradeDate = {
        ...whereClause.tradeDate,
        lte: new Date(endDate)
      };
    }

    const historyData = await this.prisma.stockDailyData.findMany({
      where: whereClause,
      orderBy: { tradeDate: 'asc' },
      take: 1000 // 限制返回数据量
    });

    // 转换BigInt为字符串
    return historyData.map(data => ({
      ...data,
      volume: data.volume ? data.volume.toString() : null
    }));
  }

  // 获取股票评分
  async getStockRating(stockId: number) {
    const rating = await this.prisma.stockRating.findFirst({
      where: { stockId },
      orderBy: { ratingDate: 'desc' }
    });

    return rating;
  }

  // 搜索股票
  async searchStocks(keyword: string, categoryKey?: string) {
    // 基础搜索条件
    const searchConditions = {
      OR: [
        { stockCode: { contains: keyword } },
        { stockName: { contains: keyword } }
      ]
    };

    // 如果指定了大分类，需要添加分类过滤条件
    let whereClause: any = searchConditions;
    if (categoryKey) {
      // 获取大分类下的股票ID列表
      const categoryStocks = await this.getCategoryStocks(categoryKey);
      const stockIds = categoryStocks.map(stock => stock.id);
      
      if (stockIds.length > 0) {
        whereClause = {
          AND: [
            searchConditions,
            { id: { in: stockIds } }
          ]
        };
      } else {
        // 如果该分类下没有股票，返回空结果
        return [];
      }
    }

    const stocks = await this.prisma.stock.findMany({
      where: whereClause,
      include: {
        market: true,
        realtime: true
      },
      take: 20
    });

    // 转换BigInt为字符串
    return stocks.map(stock => ({
      ...stock,
      totalShares: stock.totalShares ? stock.totalShares.toString() : null,
      outstandingShares: stock.outstandingShares ? stock.outstandingShares.toString() : null,
      realtime: stock.realtime ? {
        ...stock.realtime,
        volume: stock.realtime.volume ? stock.realtime.volume.toString() : null
      } : null
    }));
  }

  // 获取大分类下的所有股票（复用StockCategoryService的逻辑）
  private async getCategoryStocks(categoryKey: string) {
    // 定义子分类接口
    interface SubCategory {
      key: string;
      name: string;
      markets: string[];
      codePattern?: RegExp;
    }

    // 大分类和小分类的层级结构定义（与StockCategoryService保持一致）
    const CATEGORY_HIERARCHY = [
      {
        key: 'a_stock',
        name: 'A股市场',
        description: '中国内地A股市场',
        subCategories: [
          { key: 'sh_a', name: '上证A股', markets: ['SH'], codePattern: /^6/ },
          { key: 'sz_a', name: '深证A股', markets: ['SZ'], codePattern: /^00/ },
          { key: 'cy', name: '创业板', markets: ['SZ'], codePattern: /^3/ },
          { key: 'kc', name: '科创板', markets: ['SH'], codePattern: /^68/ },
          { key: 'bj', name: '北证A股', markets: ['BJ'], codePattern: /^8/ }
        ] as SubCategory[]
      },
      {
        key: 'hk_stock',
        name: '港股市场',
        description: '香港联合交易所',
        subCategories: [
          { key: 'hk_main', name: '港股主板', markets: ['HK'] }
        ] as SubCategory[]
      },
      {
        key: 'us_stock',
        name: '美股市场',
        description: '美国股票市场',
        subCategories: [
          { key: 'nasdaq', name: 'NASDAQ', markets: ['NASDAQ'] },
          { key: 'nyse', name: 'NYSE', markets: ['NYSE'] }
        ] as SubCategory[]
      },
      {
        key: 'uk_stock',
        name: '英股市场',
        description: '英国股票市场',
        subCategories: [
          { key: 'lse', name: 'LSE', markets: ['LSE'] }
        ] as SubCategory[]
      }
    ];

    const mainCategory = CATEGORY_HIERARCHY.find(cat => cat.key === categoryKey);
    if (!mainCategory) {
      return [];
    }

    const allStocks = [];
    
    for (const subCategory of mainCategory.subCategories) {
      const whereClause: any = { status: 1 };
      
      // 市场过滤
      if (subCategory.markets && subCategory.markets.length > 0) {
        const marketIds = await this.getMarketIds(subCategory.markets);
        whereClause.marketId = { in: marketIds };
      }

      // 股票代码规则过滤
      if (subCategory.codePattern) {
        const categoryStocks = await this.prisma.stock.findMany({
          where: {
            marketId: whereClause.marketId,
            status: 1
          },
          select: { id: true, stockCode: true }
        });

        const filteredStocks = categoryStocks.filter(stock => 
          subCategory.codePattern!.test(stock.stockCode)
        );
        
        allStocks.push(...filteredStocks);
      } else {
        const categoryStocks = await this.prisma.stock.findMany({
          where: whereClause,
          select: { id: true, stockCode: true }
        });
        
        allStocks.push(...categoryStocks);
      }
    }

    return allStocks;
  }


  // 获取市场概览
  async getMarketOverview() {
    const markets = await this.prisma.market.findMany({
      where: { status: 1 },
      include: {
        _count: {
          select: { stocks: true }
        }
      }
    });

    // 获取各市场的统计数据
    const overview = await Promise.all(
      markets.map(async (market) => {
        const stats = await this.prisma.stockRealtime.aggregate({
          where: {
            stock: { marketId: market.id }
          },
          _avg: { changePercent: true },
          _count: true
        });

        return {
          market: market.marketName,
          marketCode: market.marketCode,
          totalStocks: market._count.stocks,
          avgChangePercent: stats._avg.changePercent || 0,
          activeStocks: stats._count
        };
      })
    );

    return overview;
  }

  // 获取大盘评分
  async getMarketRating(marketCode?: string) {
    // 默认使用A股市场，如果指定了市场则使用指定市场
    const targetMarketCode = marketCode || 'SH';
    const market = await this.prisma.market.findFirst({
      where: { marketCode: targetMarketCode }
    });

    if (!market) {
      throw new Error(`找不到${targetMarketCode}市场数据`);
    }

    // 获取指定市场所有股票的实时数据
    const realtimeData = await this.prisma.stockRealtime.findMany({
      where: {
        stock: { marketId: market.id }
      }
    });

    if (realtimeData.length === 0) {
      return { rating: 5, description: '暂无数据' };
    }

    // 计算涨跌统计
    const riseCount = realtimeData.filter(item => 
      item.changePercent && parseFloat(item.changePercent.toString()) > 0
    ).length;
    const fallCount = realtimeData.filter(item => 
      item.changePercent && parseFloat(item.changePercent.toString()) < 0
    ).length;
    const flatCount = realtimeData.filter(item => 
      !item.changePercent || parseFloat(item.changePercent.toString()) === 0
    ).length;

    // 计算平均涨跌幅
    const avgChange = realtimeData.reduce((sum, item) => {
      return sum + (item.changePercent ? parseFloat(item.changePercent.toString()) : 0);
    }, 0) / realtimeData.length;

    // 基于涨跌比例和平均涨跌幅计算评分
    const riseRatio = riseCount / realtimeData.length;
    let rating = 5; // 默认中性评分

    if (avgChange > 2) {
      rating = 9; // 大涨
    } else if (avgChange > 1) {
      rating = 8; // 上涨
    } else if (avgChange > 0.5) {
      rating = 7; // 微涨
    } else if (avgChange > -0.5) {
      rating = 5; // 平稳
    } else if (avgChange > -1) {
      rating = 4; // 微跌
    } else if (avgChange > -2) {
      rating = 3; // 下跌
    } else {
      rating = 2; // 大跌
    }

    // 根据上涨股票比例调整评分
    if (riseRatio > 0.7) {
      rating = Math.min(10, rating + 1);
    } else if (riseRatio < 0.3) {
      rating = Math.max(1, rating - 1);
    }

    const descriptions = {
      1: '极度悲观', 2: '非常悲观', 3: '悲观', 4: '偏悲观', 5: '中性',
      6: '偏乐观', 7: '乐观', 8: '非常乐观', 9: '极度乐观', 10: '狂欢'
    };

    return {
      rating: Math.round(rating),
      description: descriptions[Math.round(rating) as keyof typeof descriptions] || '中性',
      statistics: {
        totalStocks: realtimeData.length,
        riseCount,
        fallCount,
        flatCount,
        riseRatio: Math.round(riseRatio * 10000) / 100, // 百分比保留2位小数
        avgChange: Math.round(avgChange * 100) / 100
      }
    };
  }

  // 获取涨跌分布统计
  async getRiseFallDistribution(marketCode?: string) {
    // 默认使用A股市场，如果指定了市场则使用指定市场
    const targetMarketCode = marketCode || 'SH';
    const market = await this.prisma.market.findFirst({
      where: { marketCode: targetMarketCode }
    });

    if (!market) {
      throw new Error(`找不到${targetMarketCode}市场数据`);
    }

    // 获取今天的实时数据
    const realtimeData = await this.prisma.stockRealtime.findMany({
      where: {
        stock: { marketId: market.id }
      }
    });

    // 涨跌停统计
    const limitUp = realtimeData.filter(item => 
      item.changePercent && parseFloat(item.changePercent.toString()) >= 9.8
    ).length;
    
    const limitDown = realtimeData.filter(item => 
      item.changePercent && parseFloat(item.changePercent.toString()) <= -9.8
    ).length;

    // 涨跌幅区间统计
    const ranges = {
      'rise_over_5': 0,    // 涨超5%
      'rise_3_to_5': 0,    // 涨3%-5%
      'rise_1_to_3': 0,    // 涨1%-3%
      'rise_0_to_1': 0,    // 涨0%-1%
      'fall_0_to_1': 0,    // 跌0%-1%
      'fall_1_to_3': 0,    // 跌1%-3%
      'fall_3_to_5': 0,    // 跌3%-5%
      'fall_over_5': 0     // 跌超5%
    };

    realtimeData.forEach(item => {
      const change = item.changePercent ? parseFloat(item.changePercent.toString()) : 0;
      
      if (change > 5) {
        ranges.rise_over_5++;
      } else if (change > 3) {
        ranges.rise_3_to_5++;
      } else if (change > 1) {
        ranges.rise_1_to_3++;
      } else if (change > 0) {
        ranges.rise_0_to_1++;
      } else if (change > -1) {
        ranges.fall_0_to_1++;
      } else if (change > -3) {
        ranges.fall_1_to_3++;
      } else if (change > -5) {
        ranges.fall_3_to_5++;
      } else {
        ranges.fall_over_5++;
      }
    });

    // 获取昨日涨停今日跟跌的股票数量
    // 这里简化处理，实际应该查询昨日涨停股票的今日表现
    const yesterdayLimitUpTodayFall = Math.floor(limitUp * 0.2); // 简化估算

    return {
      limitUp,
      limitDown,
      yesterdayLimitUpTodayFall,
      distribution: ranges,
      totalStocks: realtimeData.length,
      timestamp: new Date()
    };
  }

  // 更新实时数据（内部方法）
  private async updateRealtimeData(stockId: number, data: any) {
    await this.prisma.stockRealtime.upsert({
      where: { stockId },
      update: {
        currentPrice: data.currentPrice,
        openPrice: data.openPrice,
        closePrice: data.closePrice,
        highPrice: data.highPrice,
        lowPrice: data.lowPrice,
        volume: data.volume,
        turnover: data.turnover,
        changeAmount: data.changeAmount,
        changePercent: data.changePercent
      },
      create: {
        stockId,
        currentPrice: data.currentPrice,
        openPrice: data.openPrice,
        closePrice: data.closePrice,
        highPrice: data.highPrice,
        lowPrice: data.lowPrice,
        volume: data.volume,
        turnover: data.turnover,
        changeAmount: data.changeAmount,
        changePercent: data.changePercent
      }
    });
  }

  // 获取涨跌停统计
  async getLimitUpDown(mainCategoryKey?: string) {
    // 如果没有指定大分类，默认使用A股市场
    const targetMainCategory = mainCategoryKey || 'a_stock';
    const { stocks, mainCategory } = await this.getStocksByMainCategory(targetMainCategory);

    // 从股票数据中提取实时数据
    const realtimeData = stocks.map(stock => stock.realtime).filter(Boolean);

    // 涨停股票
    const limitUpStocks = stocks.filter(stock => 
      stock.realtime?.changePercent && parseFloat(stock.realtime.changePercent.toString()) >= 9.8
    );
    
    // 跌停股票
    const limitDownStocks = stocks.filter(stock => 
      stock.realtime?.changePercent && parseFloat(stock.realtime.changePercent.toString()) <= -9.8
    );

    return {
      mainCategory: {
        key: mainCategory.key,
        name: mainCategory.name
      },
      limitUp: {
        count: limitUpStocks.length,
        stocks: limitUpStocks.map(stock => ({
          stockId: stock.id,
          stockCode: stock.stockCode,
          stockName: stock.stockName,
          marketCode: stock.market.marketCode,
          currentPrice: stock.realtime!.currentPrice.toString(),
          changePercent: stock.realtime!.changePercent?.toString(),
          volume: stock.realtime!.volume?.toString(),
          turnover: stock.realtime!.turnover?.toString()
        }))
      },
      limitDown: {
        count: limitDownStocks.length,
        stocks: limitDownStocks.map(stock => ({
          stockId: stock.id,
          stockCode: stock.stockCode,
          stockName: stock.stockName,
          marketCode: stock.market.marketCode,
          currentPrice: stock.realtime!.currentPrice.toString(),
          changePercent: stock.realtime!.changePercent?.toString(),
          volume: stock.realtime!.volume?.toString(),
          turnover: stock.realtime!.turnover?.toString()
        }))
      },
      totalStocks: stocks.length,
      timestamp: new Date()
    };
  }

  // 获取昨日涨停今日收益统计
  async getYesterdayLimitUpTodayReturn(mainCategoryKey?: string) {
    // 如果没有指定大分类，默认使用A股市场
    const targetMainCategory = mainCategoryKey || 'a_stock';
    const { stocks, mainCategory } = await this.getStocksByMainCategory(targetMainCategory);
    
    const today = new Date();
    const yesterday = new Date(today);
    yesterday.setDate(yesterday.getDate() - 1);
    
    // 格式化日期为YYYY-MM-DD
    const formatDate = (date: Date) => {
      return date.toISOString().split('T')[0];
    };

    // 获取大分类下股票的ID列表
    const stockIds = stocks.map(stock => stock.id);
    
    if (stockIds.length === 0) {
      return {
        mainCategory: {
          key: mainCategory.key,
          name: mainCategory.name
        },
        summary: {
          totalYesterdayLimitUp: 0,
          todayRise: 0,
          todayFall: 0,
          todayFlat: 0,
          riseRate: '0%',
          fallRate: '0%'
        },
        stocks: [],
        timestamp: new Date()
      };
    }

    // 获取昨日交易数据，筛选涨停股票（涨幅 >= 9.8%）
    const yesterdayLimitUpStocks = await this.prisma.stockDailyData.findMany({
      where: {
        stockId: { in: stockIds },
        tradeDate: new Date(formatDate(yesterday) + 'T00:00:00.000Z'),
        changePercent: {
          gte: 9.8
        }
      },
      include: {
        stock: {
          include: {
            market: true,
            realtime: true
          }
        }
      }
    });

    // 计算今日表现
    const results = yesterdayLimitUpStocks.map(item => {
      const todayChange = item.stock.realtime?.changePercent 
        ? parseFloat(item.stock.realtime.changePercent.toString()) 
        : 0;

      return {
        stockId: item.stockId,
        stockCode: item.stock.stockCode,
        stockName: item.stock.stockName,
        marketCode: item.stock.market.marketCode,
        yesterdayChangePercent: item.changePercent?.toString(),
        yesterdayClosePrice: item.closePrice.toString(),
        todayCurrentPrice: item.stock.realtime?.currentPrice?.toString(),
        todayChangePercent: item.stock.realtime?.changePercent?.toString(),
        returnType: todayChange > 0 ? 'rise' : todayChange < 0 ? 'fall' : 'flat'
      };
    });

    // 统计分析
    const riseCount = results.filter(item => item.returnType === 'rise').length;
    const fallCount = results.filter(item => item.returnType === 'fall').length;
    const flatCount = results.filter(item => item.returnType === 'flat').length;

    return {
      mainCategory: {
        key: mainCategory.key,
        name: mainCategory.name
      },
      summary: {
        totalYesterdayLimitUp: results.length,
        todayRise: riseCount,
        todayFall: fallCount,
        todayFlat: flatCount,
        riseRate: results.length > 0 ? (riseCount / results.length * 100).toFixed(2) + '%' : '0%',
        fallRate: results.length > 0 ? (fallCount / results.length * 100).toFixed(2) + '%' : '0%'
      },
      stocks: results,
      timestamp: new Date()
    };
  }
}